/*
ont-space - The ontology-based resource metadata repository
Copyright (c) 2006-2008, Information Eng. Research Unit - Univ. of Alcalá
http://www.cc.uah.es/ie
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at your option)
any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package org.ontspace.util.translator.lom2owl.owl;

import org.ieee.ltsc.lom.LOM;
import org.ieee.ltsc.lom.LOMUtil;
import org.ieee.ltsc.lom.LOM.Relation.Resource.Identifier;
import org.ieee.ltsc.lom.LOM.Relation.Resource.Description;

import java.io.*;
import com.hp.hpl.jena.ontology.*;
import com.hp.hpl.jena.rdf.model.RDFNode;

/**
 * 
 * Translates a LOM relation element to its representation in OWL. 
 */
public class R2RTranslator extends ElementTranslatorImpl {

    private String category =
            new String();
    private String attributeName =
            new String();
    private String element =
            new String();

    /** Creates a new instance of R2RTranslator */
    public R2RTranslator(String elementCategory, String elementElement,
            String elementAttribute) {

        this.category =
                elementCategory;
        this.attributeName =
                elementAttribute;
        this.element =
                elementElement;
    }

    /**
     * This method translates a LOM techincal requirement item to its representation 
     * in OWL. 
     * @param lom The metadata record
     * @param ont The ontology
     * @param inst The instance of learning Object
     * @param nsName The namespace
     * @param errorWriter The error file
     */
    public void apply(LOM lom, OntModel ont, Individual inst, String nsName,
            PrintWriter errorWriter) {

        String instance =
                null;

        // 1) Get the information from lom xml file

        if (category.equals("Relation")) {
            OntClass relationClass =
                    ont.getOntClass(nsName + "#lomRelation");
            OntClass langStringClass =
                    ont.getOntClass(nsName + "#langString");
            OntClass singleLangStringClass =
                    ont.getOntClass(nsName +
                    "#singleLangString");
            OntClass resourceClass =
                    ont.getOntClass(nsName + "#lomResource");
            OntClass identifierClass =
                    ont.getOntClass(nsName + "#lomIdentifier");

            DatatypeProperty relationKindProperty =
                    ont.getDatatypeProperty(nsName + "#relationKind");
            DatatypeProperty catalogProperty =
                    ont.getDatatypeProperty(nsName +
                    "#inCatalog");
            DatatypeProperty entryProperty =
                    ont.getDatatypeProperty(nsName +
                    "#isEntry");
            DatatypeProperty hasValueProperty =
                    ont.getDatatypeProperty(nsName +
                    "#hasValue");
            DatatypeProperty inLanguageProperty =
                    ont.getDatatypeProperty(nsName + "#inLanguage");


            ObjectProperty descriptionProperty =
                    ont.getObjectProperty(nsName +
                    "#hasResourceDescription");
            ObjectProperty relatedResourceProperty =
                    ont.getObjectProperty(nsName + "#relatedResource");
            ObjectProperty relationProperty =
                    ont.getObjectProperty(nsName +
                    "#hasRelation");
            ObjectProperty resourceIdProperty =
                    ont.getObjectProperty(nsName +
                    "#hasResourceIdentifier");
            ObjectProperty includeLangStringProperty =
                    ont.getObjectProperty(nsName + "#includesSingleLangString");

            int i =
                    0;

            while (LOMUtil.getRelation((lom), i) != null) {

                //create the relation instance
                instance =
                        "#relation" +
                        inst.getLocalName() + "-" + String.valueOf(i);

                Individual relationInstance =
                        ont.createIndividual(nsName +
                        instance, relationClass);

                //7.1 relation kind              

                String relationKindLOM =
                        String.valueOf(LOMUtil.getValue(LOMUtil.getRelationKind(lom,
                        i)));

                if (relationKindLOM != null) {
                    RDFNode relationKindValue =
                            ont.createTypedLiteral(relationKindLOM);
                    relationInstance.setPropertyValue(relationKindProperty,
                            relationKindValue);
                } else {
                    String log =
                            "The Kind field of the Relation category must contain a value";
                    errorWriter.println(log);
                }

                //7.2 resource                
                if (LOMUtil.getRelationResource(lom, i) == null) {
                    String log =
                            "The Resource field of the Relation category must contain a value";
                    errorWriter.println(log);
                } else {
                    instance =
                            "#relationR" +
                            inst.getLocalName() + "-" + String.valueOf(i);

                    Individual resourceInstance =
                            ont.createIndividual(nsName +
                            instance, resourceClass);

                    int j =
                            0;

                    //7.2.1 resource identifier
                    //create the identifier instance
                    while (LOMUtil.getRelationResourceIdentifier(lom, i, j) !=
                            null) {
                        instance =
                                "#idR" +
                                inst.getLocalName() + "-" + String.valueOf(j);
                        Individual instanceIdentifier =
                                ont.createIndividual(nsName + instance,
                                identifierClass);

                        Identifier iden =
                                LOMUtil.getRelationResourceIdentifier(lom, i, j);
                        String catalogLOM =
                                iden.getCatalog();
                        String entryLOM =
                                iden.getEntry();

                        if (catalogLOM != null) {
                            RDFNode catalogValue =
                                    ont.createTypedLiteral(catalogLOM);
                            instanceIdentifier.setPropertyValue(catalogProperty,
                                    catalogValue);
                        } else {
                            String log =
                                    "The Catalog field of the Relation category must contain a value";
                            errorWriter.println(log);
                        }
                        if (entryLOM != null) {
                            RDFNode entryValue =
                                    ont.createTypedLiteral(entryLOM);
                            instanceIdentifier.setPropertyValue(entryProperty,
                                    entryValue);
                        } else {
                            String log =
                                    "The Entry field of the Relation category must contain a value";
                            errorWriter.println(log);
                        }
                        j++;
                        resourceInstance.addProperty(resourceIdProperty,
                                instanceIdentifier);
                    }

                    //7.2.2 relation description instance
                    //create the description instance                                       
                    j =
                            0;
                    while (LOMUtil.getRelationResourceDescription(lom, i, j) !=
                            null) {

                        Description des =
                                LOMUtil.getRelationResourceDescription(lom, i, j);

                        instance =
                                "#lsRD" +
                                inst.getLocalName() + "-" + String.valueOf(j);
                        Individual langInstance =
                                ont.createIndividual(nsName +
                                instance, langStringClass);
                        int k =
                                0;
                        while (LOMUtil.getString(LOMUtil.getRelationResourceDescription(lom,
                                i, j), k) != null) {
                            String descriptionLOM =
                                    LOMUtil.getString(LOMUtil.getRelationResourceDescription(lom,
                                    i, j), k);
                            String languageLOM =
                                    LOMUtil.getLanguage(LOMUtil.getRelationResourceDescription(lom,
                                    i, j), k);

                            instance =
                                    "#slsRD" +
                                    inst.getLocalName() + "-" +
                                    String.valueOf(k);
                            Individual singleInstance =
                                    ont.createIndividual(nsName + instance,
                                    singleLangStringClass);

                            if (descriptionLOM != null) {
                                RDFNode descriptionValue =
                                        ont.createTypedLiteral(descriptionLOM);
                                singleInstance.setPropertyValue(hasValueProperty,
                                        descriptionValue);
                            } else {
                                String log =
                                        "The RelationResourceDescription field of the Relation category must contain a value";
                                errorWriter.println(log);
                            }
                            if (languageLOM != null) {
                                RDFNode languageValue =
                                        ont.createTypedLiteral(languageLOM);
                                singleInstance.setPropertyValue(inLanguageProperty,
                                        languageValue);
                            } else {
                                String log =
                                        "The Language field of RelationResourceDescription in the Relation category must contain a value";
                                errorWriter.println(log);
                            }
                            langInstance.addProperty(includeLangStringProperty,
                                    singleInstance);

                            k++;
                        }
                        resourceInstance.addProperty(descriptionProperty,
                                langInstance);
                        j++;
                        k =
                                0;
                    }

                    relationInstance.setPropertyValue(relatedResourceProperty,
                            resourceInstance);
                    inst.addProperty(relationProperty, relationInstance);
                }
                i++;
            }//while 


        }
    }
}
